﻿// Decompiled with JetBrains decompiler
// Type: DnProcessSimulateCommands.InterferenceVolumeQuery.Tree.TreeList
// Assembly: DnProcessSimulateCommands, Version=2402.0.0.890, Culture=neutral, PublicKeyToken=null
// MVID: A885D881-AEDF-447E-852A-6F13102E089C
// Assembly location: C:\Program Files\Tecnomatix_2402\eMPower\DotNetCommands\DnProcessSimulateCommands.dll

using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;


namespace DnProcessSimulateCommands.InterferenceVolumeQuery.Tree;

public class TreeList : ListView
{
  private ITreeModel _model;
  private TreeNode _root;

  internal ObservableCollectionAdv<TreeNode> Rows { get; private set; }

  public event ExpandedValueChangedEventHandler ExpandedValueChanged;

  public ITreeModel Model
  {
    get => this._model;
    set
    {
      if (this._model == value)
        return;
      this._model = value;
      this._root.Children.Clear();
      this.Rows.Clear();
      this.CreateChildrenNodes(this._root);
    }
  }

  internal TreeNode Root => this._root;

  public ReadOnlyCollection<TreeNode> Nodes => this.Root.Nodes;

  internal TreeNode PendingFocusNode { get; set; }

  public ICollection<TreeNode> SelectedNodes
  {
    get => (ICollection<TreeNode>) this.SelectedItems.Cast<TreeNode>().ToArray<TreeNode>();
  }

  public TreeNode SelectedNode
  {
    get => this.SelectedItems.Count > 0 ? this.SelectedItems[0] as TreeNode : (TreeNode) null;
  }

  public object GetModelRootNode => this._model.RootNode;

  public TreeList()
  {
    this.Rows = new ObservableCollectionAdv<TreeNode>();
    this._root = new TreeNode(this, (object) null);
    this._root.IsExpanded = true;
    this.ItemsSource = (IEnumerable) this.Rows;
    this.ItemContainerGenerator.StatusChanged += new EventHandler(this.ItemContainerGeneratorStatusChanged);
  }

  private void ItemContainerGeneratorStatusChanged(object sender, EventArgs e)
  {
    if (this.ItemContainerGenerator.Status != GeneratorStatus.ContainersGenerated || this.PendingFocusNode == null)
      return;
    if (this.ItemContainerGenerator.ContainerFromItem((object) this.PendingFocusNode) is TreeListItem treeListItem)
      treeListItem.Focus();
    this.PendingFocusNode = (TreeNode) null;
  }

  protected override DependencyObject GetContainerForItemOverride()
  {
    return (DependencyObject) new TreeListItem();
  }

  protected override bool IsItemItsOwnContainerOverride(object item) => item is TreeListItem;

  protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
  {
    TreeListItem treeListItem = element as TreeListItem;
    TreeNode treeNode = item as TreeNode;
    if (treeListItem == null || treeNode == null)
      return;
    treeListItem.Node = item as TreeNode;
    base.PrepareContainerForItemOverride(element, treeNode.Tag);
  }

  internal void SetIsExpanded(TreeNode node, bool value)
  {
    if (value)
    {
      if (!node.IsExpandedOnce)
      {
        node.IsExpandedOnce = true;
        node.AssignIsExpanded(value);
        this.CreateChildrenNodes(node);
      }
      else
      {
        node.AssignIsExpanded(value);
        this.CreateChildrenRows(node);
      }
    }
    else
    {
      this.DropChildrenRows(node, false);
      node.AssignIsExpanded(value);
    }
    if (this.ExpandedValueChanged == null)
      return;
    this.ExpandedValueChanged();
  }

  internal void CreateChildrenNodes(TreeNode node)
  {
    IEnumerable children = this.GetChildren(node);
    if (children == null)
      return;
    int num = this.Rows.IndexOf(node);
    node.ChildrenSource = children as INotifyCollectionChanged;
    foreach (object tag in children)
    {
      TreeNode parent = new TreeNode(this, tag);
      parent.HasChildren = this.HasChildren(parent);
      node.Children.Add(parent);
    }
    this.Rows.InsertRange(num + 1, (IEnumerable<TreeNode>) node.Children.ToArray<TreeNode>());
  }

  private void CreateChildrenRows(TreeNode node)
  {
    int num = this.Rows.IndexOf(node);
    if (num < 0 && node != this._root)
      return;
    TreeNode[] array = node.AllVisibleChildren.ToArray<TreeNode>();
    this.Rows.InsertRange(num + 1, (IEnumerable<TreeNode>) array);
  }

  internal void DropChildrenRows(TreeNode node, bool removeParent)
  {
    int index = this.Rows.IndexOf(node);
    if (index < 0 && node != this._root)
      return;
    int visibleChildrenCount = node.VisibleChildrenCount;
    if (removeParent)
      ++visibleChildrenCount;
    else
      ++index;
    this.Rows.RemoveRange(index, visibleChildrenCount);
  }

  private IEnumerable GetChildren(TreeNode parent)
  {
    return this.Model != null ? this.Model.GetChildren(parent.Tag) : (IEnumerable) null;
  }

  private bool HasChildren(TreeNode parent)
  {
    if (parent == this.Root)
      return true;
    return this.Model != null && this.Model.HasChildren(parent.Tag);
  }

  internal void InsertNewNode(TreeNode parent, object tag, int rowIndex, int index)
  {
    TreeNode parent1 = new TreeNode(this, tag);
    parent1.HasChildren = this.HasChildren(parent1);
    if (index >= 0 && index < parent.Children.Count)
    {
      parent.Children.Insert(index, parent1);
    }
    else
    {
      index = parent.Children.Count;
      parent.Children.Add(parent1);
    }
    this.Rows.Insert(rowIndex + index + 1, parent1);
  }

  public void ClearSelection() => this.SelectedItem = (object) null;
}
